/*
   Copyright (c) 2005 Lucas Mello Schnorr <schnorr@gmail.com>
   
   This file is part of DIMVisual.
   
   DIMVisual is free software; you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.
   
   DIMVisual is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   for more details.
   
   You should have received a copy of the GNU Lesser General Public License
   along with DIMVisual; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include "MPIRASTROConverter.h"

static AllToOne *gather;
//static int size = -1;

@implementation MPIRASTROConverter (Gather)
- (id) convertEventGather: (GEvent *) event
{
	NSMutableArray *ret = nil;
	NSString *container;
	int i;

	GFields *f = [event fields];

	NSString *machine, *thread, *node, *identifier, *time;
	NSString *int32AtIndex0, *int32AtIndex1, *int32AtIndex2;
	NSString *stringAtIndex0;

        machine = [[f fieldWithSimpleStringKey:@"machine"] description];
        thread = [[f fieldWithSimpleStringKey: @"thread"] description];
        node = [[f fieldWithSimpleStringKey: @"node"] description];
        identifier = [[event identifier] description];
        time = [[event timestamp] description];
        int32AtIndex0 = [[f fieldWithSimpleStringKey: @"uint32-0"] description];
        int32AtIndex1 = [[f fieldWithSimpleStringKey: @"uint32-1"] description];
        int32AtIndex2 = [[f fieldWithSimpleStringKey: @"uint32-2"] description];
        stringAtIndex0 = [[f fieldWithSimpleStringKey: @"string-2"] description];

	if (gather == nil){
		gather = [[AllToOne alloc] init];
	}
//	if (allgather == nil){
//		allgather = [[NSMutableArray alloc] init];
//	}
//	if (allgatherv == nil){
//		allgatherv = [[NSMutableArray alloc] init];
//	}
	
	ret = [[NSMutableArray alloc] init];

	container = [provider identifierForEntity: 
		[NSArray arrayWithObjects: @"Machine", @"Thread", nil]
				ids:
		[NSArray arrayWithObjects: machine,thread,nil]];

	if (container == nil){
		[ret release];
		return nil;
	}
	
	int etype = atoi ([identifier cString]);

	/* MPI_ALLGATHER_IN */
	if (etype == MPI_ALLGATHER_IN){
//		NSString *sendcount = int32AtIndex0;
		NSString *size = int32AtIndex1;
		NSString *members = stringAtIndex0;

//		NSLog (@"ALL_GATHER_IN %@", container);
		for (i = 0; i < [size intValue]; i++){
//			NSLog (@"%d: entering %@(%@), root %@",i, container, time,[NSString stringWithFormat:@"%d",i]);
			[gather memberEntering: container
				andEventNode: node
				andEventTime: time
				andRootNode: [NSString stringWithFormat:@"%d",i]
				andCommSize: size
				andMembersId: members];
		}
		[ret addObject: [self addPajeSetState: @"MPI_ALLGATHER" time: time container: container]];

	/* MPI_ALLGATHER_OUT */
	}else if (etype == MPI_ALLGATHER_OUT){
//		NSString *recvcount = int32AtIndex0;
		NSString *size = int32AtIndex1;
		NSString *members = stringAtIndex0;
	
//		NSLog (@"ALL_GATHER_OUT %@", container);
		for (i = 0; i < [size intValue]; i++){
//			NSLog (@"%d: exiting %@(%@), root %@", i, container, time, [NSString stringWithFormat:@"%d",i]);
			[ret addObjectsFromArray:
				[gather memberExiting: container 
					andEventTime: time 
					andOperationName: @"allgather"
					andRootNode: [NSString stringWithFormat:@"%d",i]
					andMembersId: members
					andProvider: provider]];
		}
		[ret addObject: [self addPajeSetState: @"running" time: time container: container]];

	/* MPI_ALLGATHERV_IN */
	}else if (etype == MPI_ALLGATHERV_IN){
		[ret addObject: [self addPajeSetState: @"MPI_ALLGATHERV" time: time container: container]];

	/* MPI_ALLGATHERV_OUT */
	}else if (etype == MPI_ALLGATHERV_OUT){
		[ret addObject: [self addPajeSetState: @"running" time: time container: container]];

	/* MPI_GATHER_IN */
	}else if (etype == MPI_GATHER_IN){
//		NSString *sendcnt = int32AtIndex0;
		NSString *size = int32AtIndex1;
		NSString *root = int32AtIndex2;
		NSString *members = stringAtIndex0;
		
		[gather memberEntering: container
			andEventNode: node
			andEventTime: time
			andRootNode: root
			andCommSize: size
			andMembersId: members];
		[ret addObject: [self addPajeSetState: @"MPI_GATHER" time: time container: container]];

	/* MPI_GATHER_OUT */
	}else if (etype == MPI_GATHER_OUT){
//		NSString *recvcount = int32AtIndex0;
		NSString *root = int32AtIndex1;
		NSString *members = stringAtIndex0;
		
		[ret addObjectsFromArray: [gather memberExiting: container
			andEventTime: time
			andOperationName: @"gather"
			andRootNode: root
			andMembersId: members
			andProvider: provider]];
		[ret addObject: [self addPajeSetState: @"running" time: time container: container]];

	/* MPI_GATHERV_IN */
	}else if (etype == MPI_GATHERV_IN){
//		NSString *sendcnt = int32AtIndex0;
		NSString *size = int32AtIndex1;
		NSString *root = int32AtIndex2;
		NSString *members = stringAtIndex0;

		[gather memberEntering: container
			andEventNode: node
			andEventTime: time
			andRootNode: root
			andCommSize: size
			andMembersId: members];
		[ret addObject: [self addPajeSetState: @"MPI_GATHER" time: time container: container]];

	/* MPI_GATHERV_OUT */
	}else if (etype == MPI_GATHERV_OUT){
		NSString *root = int32AtIndex0;
		NSString *members = stringAtIndex0;

		[ret addObjectsFromArray: [gather memberExiting: container
			andEventTime: time
			andOperationName: @"gatherv"
			andRootNode: root
			andMembersId: members
			andProvider: provider]];
		[ret addObject: [self addPajeSetState: @"running" time: time container: container]];
	}
	[ret autorelease];
	return ret;
}
@end
